package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

// multipart/form-data格式用于文件上传
// gin文件上传与原生的net/http方法类似，不同在于gin把原生的request封装到c.Request中

func main() {

	r := gin.Default()
	// 限制表单上传大小 8MB，默认为32MB
	r.MaxMultipartMemory = 8 << 20

	r.POST("/upload", func(c *gin.Context) {
		file, err := c.FormFile("file") // FormFile里的字符串需与html文件中input标签里的name一致
		if err != nil {
			c.String(http.StatusInternalServerError, err.Error())
			return
		}

		err = c.SaveUploadedFile(file, "./resource/"+file.Filename)
		if err != nil {
			c.String(http.StatusInternalServerError, err.Error())
			return
		}

		// 整型转字符串 strconv.FormatInt(file.Size, 10)
		c.String(http.StatusOK, fmt.Sprintf("文件:%s 上传成功, filesize:%d bytes.", file.Filename, file.Size))
	})

	// 有的用户上传文件需要限制上传文件的类型以及上传文件的大小，
	// 但是gin框架暂时没有这些函数(也有可能是我没找到)，
	// 因此基于原生的函数写法自己写了一个可以限制大小以及文件类型的上传函数

	r.POST("/uploadspecifed", func(c *gin.Context) {
		// headers, err := c.FormFile("fileSpecified")	// 一样
		_, headers, err := c.Request.FormFile("fileSpecified")
		if err != nil {
			c.String(http.StatusOK, "Error when try to get file, err:"+err.Error())
			return
		}

		//headers.Size 获取文件大小
		if headers.Size > (8 << 20) {
			c.String(http.StatusOK, "文件太大了")
			return
		}

		//headers.Header.Get("Content-Type")获取上传文件的类型
		if headers.Header.Get("Content-Type") != "image/png" {
			c.String(http.StatusOK, "只允许上传png图片")
			return
		}

		c.SaveUploadedFile(headers, "./resource/"+headers.Filename)
		c.String(http.StatusOK, "图片: "+headers.Filename+" 上传成功")
	})

	// 上传多个文件
	r.POST("/multiupload", func(c *gin.Context) {
		form, err := c.MultipartForm()
		if err != nil {
			c.String(http.StatusBadRequest, err.Error())
			return
		}

		// 获取所有文件
		files := form.File["files"]

		// 遍历所有图片
		for _, file := range files {
			// 逐个存
			err = c.SaveUploadedFile(file, "./resource/"+file.Filename)
			if err != nil {
				c.String(http.StatusBadRequest, file.Filename+":"+err.Error())
				return
			}
		}

		c.String(http.StatusOK, fmt.Sprintf("upload %d files ok", len(files)))
	})

	r.Run(":80")
}
